import gov.nih.mipav.model.structures.ModelImage;
import gov.nih.mipav.model.structures.VOI;
import gov.nih.mipav.model.structures.VOIVector;
import gov.nih.mipav.view.ViewUserInterface;

import java.awt.BorderLayout;
import java.awt.Component;
import java.awt.Dimension;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.ArrayList;

import javax.swing.DefaultListSelectionModel;
import javax.swing.JButton;
import javax.swing.JList;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.border.TitledBorder;

public class VOIManager extends ListModule implements Drawable, MethodRelated,
    ActionListener {

  private VOIVector voiVector;

  private static VOIManager theInstance;

  private VOIManager() {
    super(DefaultListSelectionModel.SINGLE_SELECTION);
    voiVector = new VOIVector();
  }

  public static VOIManager getInstance() {
    if (theInstance == null) {
      theInstance = new VOIManager();
    }
    return theInstance;
  }

  @Override
  public boolean needsToBeUpdated() {
    return true;
  }

  @Override
  protected void updateMe() {
    this.updateAddedVOIs();
    this.removeAllObjects();
    this.addNewVOIs();
  }

  private void addNewVOIs() {
    for (Object voi : this.voiVector.toArray()) {
      if (!this.containsObject(voi)) {
        String name = ((VOI) voi).getName() + " - "
            + RegionManager.getInstance().getRegion((VOI) voi);
        this.addObject(name);
      }
    }
  }

  /**
   * Takes all added images and gets all its voi to added into the same list.
   */
  private void updateAddedVOIs() {
    voiVector.removeAllElements();
    ArrayList<String> images = ImageManager.getInstance().getImagesNames();
    for (String imageName : images) {
      ModelImage image = ViewUserInterface.getReference()
          .getRegisteredImageByName(imageName);

      VOIVector registeredVOIS = image.getVOIs();
      for (VOI voi : registeredVOIS) {
        voiVector.add(voi);
      }
    }
  }

  @Override
  public Component drawContentPane() {
    // VOI pane
    JPanel voisPane = new JPanel();
    voisPane.setBorder(new TitledBorder("VOI list"));

    voisPane.setLayout(new BorderLayout(2, 4));

    JList list = this.getList();
    JScrollPane listScroller = new JScrollPane(list);
    listScroller.setPreferredSize(new Dimension(250, 80));
    voisPane.add(listScroller, BorderLayout.CENTER);

    JButton refreshButton = new JButton("Ungroup VOIs");
    voisPane.add(refreshButton, BorderLayout.SOUTH);
    refreshButton.setActionCommand(Settings.UNGROUP_VOIS);
    refreshButton.addActionListener(this);
    return voisPane;
  }

  @Override
  public void setEnable(boolean enable) {
  }

  @Override
  public void updateProxy() {
    // TODO Auto-generated method stub

  }

  @Override
  public void actionPerformed(ActionEvent arg0) {
    if (arg0.getActionCommand() == Settings.UNGROUP_VOIS) {
      this.ungroupVois();
      this.update();
    }
  }

  private void ungroupVois() {
    voiVector.removeAllElements();
    ArrayList<String> images = ImageManager.getInstance().getImagesNames();
    for (String imageName : images) {
      ModelImage image = ViewUserInterface.getReference()
          .getRegisteredImageByName(imageName);

      VOIVector registeredVOIS = image.getVOIs();
      for (VOI voi : registeredVOIS) {
        voi.setAllActive(true);
      }
      image.ungroupVOIs();
      for (VOI voi : registeredVOIS) {
        voi.setAllActive(false);
      }
    }

  }

  public int getVOIValue(VOI voi) {
    return this.voiVector.indexOf(voi);
  }

  @Override
  protected void modifyObject() {
    
  }

  @Override
  protected void selectObject() {
    for (VOI voi : this.voiVector) {
      voi.setAllActive(false);
    }
    int index = this.getFirstSelectedIndex();
    this.voiVector.get(index).setAllActive(true);
  }

}